using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.Security;

using llbl = SD.LLBLGen.Pro.ORMSupportClasses;
using DalFactory = Ultimate.DAL.FactoryClasses;
using Dal = Ultimate.DAL;
using DalCollection = Ultimate.DAL.CollectionClasses;
using DalEntity = Ultimate.DAL.EntityClasses;

namespace Ultimate.Download
{
    /// <summary>
    /// Summary description for EditLeague.
    /// </summary>
    public class Schedule : System.Web.UI.Page
    {
        private void Page_Load(object sender, System.EventArgs e)
        {
            // Put user code to initialize the page here
            GetSchedule();
        }

        string output = "";

        /// <summary>
        /// Gets the current schedule type from the query string.  If there is non or it's badly formatted <see cref="ScheduleType.League"/> is returned.
        /// </summary>
        public ScheduleType CurrentScheduleType
        {
            get
            {
                int temp = -1;
                int.TryParse(Request.QueryString["stype"], out temp);

                if (temp == -1)
                    return ScheduleType.League;
                else
                    return (ScheduleType)temp;
            }
        }
        /// <summary>
        /// Gets the id of the team to do a schedule for from teh query string.  This is only expected to have a value if the schedule type is team.
        /// </summary>
        public int TeamId
        {
            get
            {
                int id = -1;
                int.TryParse(Request.QueryString["id"], out id);

                return id;
            }
        }

        /// <summary>
        /// Gets the schedule for the parameters specified.
        /// </summary>
        private void GetSchedule()
        {
            string events = "";
            switch (CurrentScheduleType)
            {
                case ScheduleType.Individual:
                    events = GetIndividualSchedual();
                    break;

                case ScheduleType.Team:
                    events = BuildTeamGameSchedule(TeamId);
                    break;

                default:
                    throw new Exception("schedule parameters incorrect");
                    break;
            }

            string template = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//eupa/EUPA v2.9//EN
METHOD:REQUEST
{0}
END:VCALENDAR";

            output = string.Format(template, events);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(writer);

            Response.ContentType = "text/calendar";
            Response.AddHeader("content-disposition", "attachment; filename=schedule.ics");
            writer.Write(output);
        }

        /// <summary>
        /// Build a schedule string for the current user.
        /// </summary>
        private string GetIndividualSchedual()
        {
            string schedule = "";

            MembershipUser mu = Membership.GetUser();
            Guid userID = (Guid)mu.ProviderUserKey;


            DAL.TypedListClasses.PlayerTeamLeagueTypedList ptl = new DAL.TypedListClasses.PlayerTeamLeagueTypedList();
            llbl.PredicateExpression filter = new llbl.PredicateExpression();
            filter.Add(DalFactory.PredicateFactory.CompareValue(Dal.PlayerFieldIndex.UserID, llbl.ComparisonOperator.Equal, userID));
            filter.Add(DalFactory.PredicateFactory.CompareValue(Dal.LeagueFieldIndex.Active, llbl.ComparisonOperator.Equal, true));
            llbl.ISortExpression sorter = new llbl.SortExpression(DalFactory.SortClauseFactory.Create(Dal.TeamFieldIndex.TeamName, llbl.SortOperator.Ascending));
            ptl.Fill(0, sorter, false, filter);


            foreach (DAL.TypedListClasses.PlayerTeamLeagueRow ptlr in ptl.Rows)
            {
                //DalEntity.GameEntity ge = 
                schedule += BuildTeamGameSchedule(ptlr.TeamID);
                //if (ge != null)
                //{
                //    message += "Next Game: " + ge.GameDay.ToShortDateString() + "<br />";
                //    message += ge.Field.FieldName;
                //}
                //message += "</li>";

            }

            return schedule;
        }
        /// <summary>
        /// Build a schedule string for the specified team.
        /// </summary>
        /// <param name="teamId"></param>
        /// <returns></returns>
        private string BuildTeamGameSchedule(int teamId)
        {
            DalCollection.GameCollection gec = new DalCollection.GameCollection();

            llbl.PredicateExpression filter = new llbl.PredicateExpression();
            //filter.Add(DalFactory.PredicateFactory.CompareValue(Dal.GameFieldIndex.GameDay, llbl.ComparisonOperator.GreaterEqual, DateTime.Today));
            filter.Add(DalFactory.PredicateFactory.CompareValue(Dal.GameFieldIndex.GameDay, llbl.ComparisonOperator.GreaterEqual, DateTime.Parse("2000-1-1")));

            llbl.PredicateExpression teamFilter = new llbl.PredicateExpression();
            teamFilter.Add(DalFactory.PredicateFactory.CompareValue(Dal.GameFieldIndex.AwayTeamID, llbl.ComparisonOperator.Equal, teamId));
            teamFilter.AddWithOr(DalFactory.PredicateFactory.CompareValue(Dal.GameFieldIndex.HomeTeamID, llbl.ComparisonOperator.Equal, teamId));

            filter.AddWithAnd(teamFilter);

            llbl.ISortExpression sorter = new llbl.SortExpression(DalFactory.SortClauseFactory.Create(Dal.GameFieldIndex.GameDay, llbl.SortOperator.Ascending));
            gec.GetMulti(filter, 0, sorter);

            string iCalGames = "";
            string iCalGamesFormat = @"BEGIN:VEVENT
UID:{0}
SEQUENCE:1
DTSTAMP:{1}
ORGANIZER:{2}
DTSTART:{3}
DTEND:{4}
SUMMARY:{5}
LOCATION:{6}
DESCRIPTION:{7}
END:VEVENT
";


            foreach (DalEntity.GameEntity game in gec)
            {
                //setup calendar fields.
                //note all dates are in UTC via the ISO8601 format
                string title = "Ultimate Frisbee: " + game.Team.TeamName + " vs " + game.Team_.TeamName;
                string ISO8601Format = "yyyyMMddTHHmmssZ";
                DateTime timeStamp = DateTime.Now.ToUniversalTime();
                DateTime gameTime = DateTime.Parse(game.GameTime);
                DateTime gameStart = new DateTime(game.GameDay.Year, game.GameDay.Month, game.GameDay.Day, gameTime.Hour, gameTime.Minute, gameTime.Second);
                gameStart = gameStart.ToUniversalTime();
                string field = game.Field.FieldName;
                string description = GetICalDescription(field);

                iCalGames += string.Format(iCalGamesFormat, game.GameID.ToString(), timeStamp.ToString(ISO8601Format), "EUPA", gameStart.ToString(ISO8601Format), gameStart.AddHours(2).ToString(ISO8601Format), title, field, description);


                //                BEGIN:VCALENDAR
                //VERSION:2.0
                //PRODID:-//hacksw/handcal//NONSGML v1.0//EN
                //BEGIN:VEVENT
                //UID:uid1@example.com
                //DTSTAMP:19970714T170000Z
                //ORGANIZER;CN=John Doe:MAILTO:john.doe@example.com
                //DTSTART:19970714T170000Z
                //DTEND:19970715T035959Z
                //SUMMARY:Bastille Day Party
                //END:VEVENT
                //END:VCALENDAR
            }

            //if (gec.Items.Count > 0)
            //    return (GameEntity)gec.Items[0];
            //return null;

            return iCalGames.Trim("\r\n".ToCharArray());
        }

        /// <summary>
        /// gets a description for the event based on the name of the field .
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        private static string GetICalDescription(string field)
        {
            string description = "";

            string blueQuill = "Field Location: 11304 - 25 Ave http://goo.gl/stomG\\nField Layouts: http://goo.gl/Vf9xR\\n";
            string caernarvon = "Field Location: 14830 - 118th St http://goo.gl/JSW66\\nField Layouts: http://goo.gl/UfwAn\\n";
            string callingwood = "Field Location: 173 St - 76 Ave http://goo.gl/mOv56\\nField Layouts: http://goo.gl/amtFR\\n";
            string kaskitayo = "Field Location: 1975 - 109 St http://goo.gl/rkmL6\\nField Layouts: http://goo.gl/HsPhQ\\n";
            string kinsmen = "Field Location: 9100 Walterdale Hill http://goo.gl/OKzGD\\nField Layouts: http://goo.gl/KEoUq\\n";
            string lymburn = "Field Location: 187 St - 72 Ave http://goo.gl/1UT0h\\nField Layouts: http://goo.gl/vTEQQ\\n";
            string velmaEBaker = "Field Location: 30 St - 43 Ave http://goo.gl/oldJe\\nField Layouts: http://goo.gl/8AMoi\\n";
            string kiniski = "Field Location: 38th and 38th  http://goo.gl/URpwv\\nField Maps: http://goo.gl/M47C3\\n";

            if (field.ToLower().Contains("blue quill"))
                description = blueQuill;
            else if (field.ToLower().Contains("caernarvon"))
                description = caernarvon;
            else if (field.ToLower().Contains("callingwood"))
                description = callingwood;
            else if (field.ToLower().Contains("kaskitayo"))
                description = kaskitayo;
            else if (field.ToLower().Contains("kinsmen"))
                description = kinsmen;
            else if (field.ToLower().Contains("lymburn"))
                description = lymburn;
            else if (field.ToLower().Contains("velma"))
                description = velmaEBaker;
            else if (field.ToLower().Contains("kiniski"))
                description = kiniski;

            return description;
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.Load += new System.EventHandler(this.Page_Load);
        }
        #endregion
    }

    /// <summary>
    /// Defines the different formats the schedule will be produced in.
    /// </summary>
    public enum ScheduleFormat
    {
        iCal
    }

    /// <summary>
    /// Defines the different schedules the schedule.aspx page will produce.
    /// </summary>
    public enum ScheduleType
    {
        /// <summary>
        /// Gets the schedule for any future games for the logged in user
        /// </summary>
        Individual,
        /// <summary>
        /// Gets the schedule for a single team.  The team id must be specified via query string (eg 'tid=1')
        /// </summary>
        Team,
        /// <summary>
        /// Gets the schedule for an entire league.  The league id must be specified via query string (eg '&li=1')
        /// </summary>
        League
    }
}
